package com.ruoyi.pcwl.minio;

import com.ruoyi.pcwl.domain.MediaFiles;
import com.ruoyi.pcwl.domain.MinioFile;
import com.ruoyi.pcwl.domain.enums.MediaTypeEnum;
import com.ruoyi.pcwl.service.IMediaFilesService;
import io.minio.*;
import io.minio.errors.*;
import io.minio.messages.Item;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

@Component
@Data
public class MinioUtil {

    private static MinioClient minioClient;

    private static String bucketName;

    private static IMediaFilesService mediaFilesService;


//    private static MinioUtil minioUtil;
//
//
//    @PostConstruct
//    public void init() {
//        minioUtil = this;
//        minioUtil.minioClient = this.minioClient;
//        minioUtil.bucketName = this.bucketName;
//    }


    public  MinioClient getMinioClient() {
        return minioClient;
    }

    @Autowired
    public  void setMinioClient(MinioClient minioClient) {
        MinioUtil.minioClient = minioClient;
    }

    @Autowired
    public  void setMediaFilesService(IMediaFilesService mediaFilesService) {
        MinioUtil.mediaFilesService = mediaFilesService;
    }

    public  String getBucketName() {
        return bucketName;
    }

    @Value("${minio.bucketName}")
    public  void setBucketName(String bucketName) {
        MinioUtil.bucketName = bucketName;
    }


    public static ArrayList<MinioFile> getMediaFileList(MediaTypeEnum mediaTypeEnum) throws ErrorResponseException, InsufficientDataException, InternalException, InvalidBucketNameException, InvalidKeyException, InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, XmlParserException {

        ArrayList<Item> items = new ArrayList<>();
        ArrayList<MinioFile> minioFiles = new ArrayList<>();
        if (mediaTypeEnum==null)
        {
            for (MediaTypeEnum myEnum : MediaTypeEnum.values()) {
                Iterable<Result<Item>> results = minioClient.listObjects(
                        ListObjectsArgs.builder().bucket(bucketName).prefix(myEnum.getCategoryName()).recursive(true).build());
//                Iterable<Result<Item>> results= minioClient.listObjects(bucketName, null, true);
                for (Result<Item> myObject : results) {
                    MinioFile minioFile=new MinioFile();
                    Item item = myObject.get();
//                    System.out.println("Object Name: " + item.objectName());
                    minioFile.setObjectName(item.objectName());
//                    System.out.println("Size: " + item.size() + " bytes");
                    minioFile.setSize(item.size());
//                    System.out.println("Last Modified: " + item.lastModified().toString());
                    minioFile.setLastModified(item.lastModified().toString());
//                    System.out.println("Is Directory?: " + item.isDir());
                    minioFile.setIsDirectory(item.isDir());
//                    System.out.println("------------------------------");
//                    items.add(item);
                    minioFiles.add(minioFile);
                }
            }

        }
        else {
            //查询minio子目录
            Iterable<Result<Item>> results = minioClient.listObjects(
//                ListObjectsArgs.builder().bucket(bucketName+"/"+mediaTypeEnum.getCategoryName()).build());
                    ListObjectsArgs.builder().bucket(bucketName).prefix(mediaTypeEnum.getCategoryName()).build());
            for (Result<Item> myObject : results) {
                MinioFile minioFile=new MinioFile();
                Item item = myObject.get();
//                    System.out.println("Object Name: " + item.objectName());
                minioFile.setObjectName(item.objectName());
//                    System.out.println("Size: " + item.size() + " bytes");
                minioFile.setSize(item.size());
//                    System.out.println("Last Modified: " + item.lastModified().toString());
                minioFile.setLastModified(item.lastModified().toString());
//                    System.out.println("Is Directory?: " + item.isDir());
                minioFile.setIsDirectory(item.isDir());
//                    System.out.println("------------------------------");
//                    items.add(item);
                minioFiles.add(minioFile);
            }
        }
        return minioFiles;
    }

//    上传文件
    public static Map<String, Object>  uploadFile(MultipartFile multipartFile,MediaTypeEnum mediaTypeEnum) throws IOException, InvalidKeyException, InvalidBucketNameException, NoSuchAlgorithmException, ServerException, InsufficientDataException, XmlParserException, ErrorResponseException, InternalException, InvalidResponseException {

        // 生成随机字符串
        UUID uuid = UUID.randomUUID();
        String randomStr = uuid.toString().replaceAll("-", "").substring(0, 8);

        //子目录
        String defaultFolderPath = getDefaultFolderPath();

        String extension =multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf("."));

        String finalFilename = mediaTypeEnum.getCategoryName() + defaultFolderPath+randomStr+extension;;
        System.out.println("生成的文件名：" + finalFilename);

        InputStream in = multipartFile.getInputStream();

        //文件上传
        minioClient.putObject(
                PutObjectArgs.builder().bucket(bucketName).object(finalFilename).stream(
                                in, multipartFile.getSize(), -1)
                        .contentType(multipartFile.getContentType())
                        .build());
        in.close();

        String path = bucketName+"/"+ finalFilename;
//保存文件信息到数据库
        MediaFiles mediaFiles = new MediaFiles();
        mediaFiles.setFilename(multipartFile.getOriginalFilename());
        mediaFiles.setFilePath(path);
        mediaFiles.setBucket(bucketName);
        mediaFiles.setCategoryId(mediaTypeEnum.getCategoryId().longValue());
        mediaFiles.setCategoryName(mediaTypeEnum.getCategoryName());
        mediaFiles.setFileSize(multipartFile.getSize());
        mediaFilesService.insertMediaFiles(mediaFiles);

        Map<String, Object> map = new HashMap<>();
        map.put("path",path);
        map.put("mediaFileId",mediaFiles.getId());

        return map;
    }

//    //    上传文件
//    public static <T> String uploadFileNew(MultipartFile multipartFile, MediaTypeEnum mediaTypeEnum,T t) throws IOException, InvalidKeyException, InvalidBucketNameException, NoSuchAlgorithmException, ServerException, InsufficientDataException, XmlParserException, ErrorResponseException, InternalException, InvalidResponseException {
//
//
//        // 生成随机字符串
//        UUID uuid = UUID.randomUUID();
//
//        String randomStr = uuid.toString().replaceAll("-", "").substring(0, 8);
//
//        //子目录
//        String defaultFolderPath = getDefaultFolderPath();
//
//        String extension =multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf("."));
//
//        String finalFilename = mediaTypeEnum.getCategoryName() + defaultFolderPath+randomStr+extension;;
//        System.out.println("生成的文件名：" + finalFilename);
//
//        InputStream in = multipartFile.getInputStream();
//
//        //文件上传
//        minioClient.putObject(
//                PutObjectArgs.builder().bucket(bucketName).object(finalFilename).stream(
//                                in, multipartFile.getSize(), -1)
//                        .contentType(multipartFile.getContentType())
//                        .build());
//        in.close();
//
//        return bucketName+"/"+finalFilename;
//    }

    //获取文件默认存储目录路径 年/月/日
    private static String getDefaultFolderPath() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String folder = sdf.format(new Date()).replace("-", "/")+"/";
        return folder;
    }

}
